package com.example.pt.service.impl;

import com.example.pt.entity.TorrentFile;
import com.example.pt.entity.TorrentPromotion;
import com.example.pt.enums.PromotionType;
import com.example.pt.mapper.TorrentPromotionMapper;
import com.example.pt.repository.TorrentPromotionRepository;
import com.example.pt.repository.TorrentFileRepository;
import com.example.pt.service.PromotionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.DayOfWeek;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class PromotionServiceImpl implements PromotionService {
    private static final Logger logger = LoggerFactory.getLogger(PromotionServiceImpl.class);

    @Autowired
    private TorrentPromotionRepository promotionRepository;
    @Autowired
    private TorrentFileRepository torrentRepository;
    @Autowired
    private TorrentPromotionMapper promotionMapper;


    // 每周对下载量最低的10个种子进行免费促销
    @Override
    public void applyWeeklyFreePromotion() {
        LocalDateTime now = LocalDateTime.now();

        if (now.getDayOfWeek() != DayOfWeek.SUNDAY) {
            logger.info("当前非周日，跳过每周免费促销");
            return;
        }

        // 计算本周时间范围（周一0点 ~ 周日23:59:59）
//        LocalDateTime weekStart = now.with(DayOfWeek.MONDAY).toLocalDate().atStartOfDay();
//        LocalDateTime weekEnd = now.with(DayOfWeek.SUNDAY).toLocalDate().atTime(23, 59, 59);

        // 查询当前下载量最低的10个种子
        List<TorrentFile> lowDownloadTorrents = torrentRepository.findTop10ByUploadTimeBetweenAndDownloadCountAsc();

        if (lowDownloadTorrents.isEmpty()) {
            logger.info("本周无符合条件的种子");
            return;
        }

        // 免费促销（24小时）
        LocalDateTime promotionStart = now;
        LocalDateTime promotionEnd = now.plusDays(1);
        int freeType = PromotionType.FREE.getValue();

        for (TorrentFile torrent : lowDownloadTorrents) {
            if (isPromotionExists(torrent.getTid(), freeType, promotionStart, promotionEnd)) {
                logger.info("种子{}已存在免费促销，跳过", torrent.getTid());
                continue;
            }

            // 创建免费促销记录
            TorrentPromotion promotion = new TorrentPromotion();
            promotion.setTorrentId(torrent.getTid());
            promotion.setPromotionType(freeType);
            promotion.setStartTime(promotionStart);
            promotion.setEndTime(promotionEnd);
            promotionRepository.save(promotion);
            logger.info("为种子{}添加免费促销（{}~{}）",
                    torrent.getTid(), promotionStart, promotionEnd);
        }
    }

    // 新种子折扣促销（3天内50%，3-5天30%）
    @Override
    public void applyNewTorrentPromotion() {
        LocalDateTime now = LocalDateTime.now();

        // 处理3天内的新种子（50%折扣）
        LocalDateTime threeDaysAgo = now.minusDays(3);
        List<TorrentFile> newTorrents = torrentRepository.findByUploadTimeBetween(threeDaysAgo, now);
        handleDiscountPromotion(newTorrents, PromotionType.DISCOUNT_50, 3);

        // 处理3-5天的种子（30%折扣）
        LocalDateTime fiveDaysAgo = now.minusDays(5);
        List<TorrentFile> midTorrents = torrentRepository.findByUploadTimeBetween(fiveDaysAgo, threeDaysAgo);
        handleDiscountPromotion(midTorrents, PromotionType.DISCOUNT_30, 5);
    }

    // 处理折扣促销的通用方法
    private void handleDiscountPromotion(List<TorrentFile> torrents, PromotionType type, int days) {
        for (TorrentFile torrent : torrents) {
            LocalDateTime uploadTime = torrent.getUploadTime();
            LocalDateTime endTime = uploadTime.plusDays(days);

            // 检查是否已存在促销
            if (isPromotionExists(torrent.getTid(), type.getValue(), uploadTime, endTime)) {
                continue;
            }

            // 创建促销记录
            TorrentPromotion promotion = new TorrentPromotion();
            promotion.setTorrentId(torrent.getTid());
            promotion.setPromotionType(type.getValue());
            promotion.setStartTime(uploadTime);
            promotion.setEndTime(endTime);
            promotionRepository.save(promotion);

            logger.info("为种子{}添加{}促销（{}~{}）",
                    torrent.getTid(), type.getName(), uploadTime, endTime);
        }
    }

    // 获取当前有效的促销
    @Override
    public List<TorrentPromotion> getCurrentPromotions(Integer torrentId) {
        return promotionRepository.findByTorrentIdAndEndTimeAfter(torrentId, LocalDateTime.now());
    }

    // 获取最大折扣率（值越小折扣越大）
    @Override
    public double getMaxDiscountRate(Integer torrentId) {
        List<TorrentPromotion> promotions = getCurrentPromotions(torrentId);
        if (promotions.isEmpty()) return 1.0; // 无促销时返回原价

        return promotions.stream()
                .mapToDouble(p -> p.getPromotionTypeEnum().getDiscountRate())
                .min()
                .orElse(1.0);
    }

    // 获取最大折扣率（值越小折扣越大）
    @Override
    public Map<String, Object> getMaxDiscountInfo(Integer torrentId) {
        List<TorrentPromotion> promotions = getCurrentPromotions(torrentId);
        Map<String, Object> result = new HashMap<>();
        if (promotions.isEmpty()) {
            result.put("discountName", "暂无折扣");
            result.put("startTime", null);
            result.put("endTime", null);
            return result;
        }

        // 找到折扣力度最大的促销（promotion_type数值越小，折扣越大）
        TorrentPromotion maxDiscountPromotion = promotions.stream()
                .min(Comparator.comparingInt(TorrentPromotion::getPromotionType))
                .orElse(null);

        if (maxDiscountPromotion == null) {
            result.put("discountName", "暂无折扣");
            result.put("startTime", null);
            result.put("endTime", null);
            return result;
        }

        // 获取促销类型名称和折扣率
        String discountName = getDiscountNameByType(maxDiscountPromotion.getPromotionType());//(0=免费,1=50%,2=30%)'
//        double discountRate = getDiscountRateByType(maxDiscountPromotion.getPromotionType());

        // 获取活动时间
        LocalDateTime startTime = maxDiscountPromotion.getStartTime();
        LocalDateTime endTime = maxDiscountPromotion.getEndTime();

        result.put("discountName", discountName);
        result.put("startTime", startTime);
        result.put("endTime", endTime);
        return result;
    }

    // 辅助方法：根据促销类型获取名称（建议用枚举替代）
    private String getDiscountNameByType(int type) {
        switch (type) {
            case 0: return "免费";
            case 1: return "50%折扣";
            case 2: return "30%折扣";
            default: return "暂无折扣";
        }
    }


    @Override
    public double getCurrentPromotionsByInfoHash(String infoHash) {
        List<TorrentPromotion> promotions  = promotionMapper.getCurrentPromotionsByInfoHash(infoHash);
        if (promotions.isEmpty()) return 1.0; // 无促销时返回原价

        return promotions.stream()
                .mapToDouble(p -> p.getPromotionTypeEnum().getDiscountRate())
                .min()
                .orElse(1.0);
    }

    // 检查是否已存在促销
    public boolean isPromotionExists(Integer tid, Integer type,
                                      LocalDateTime startTime, LocalDateTime endTime) {
        return promotionRepository.existsByTorrentIdAndPromotionTypeAndStartTimeBetween(
                tid, type, startTime, endTime);
    }
}